/**
 * Execution entry point for context characteristics optimizer.
 * modified by edhong to use jargs
 * 
 * @author Yong Shin
 *
 */
import jargs.gnu.CmdLineParser;
import java.lang.reflect.Constructor;

public class Main {

    private static void printUsage() {
	System.err.println(
"Usage: java Main [--ccd ccdfilename] [--cc ccfilename (use - for stdin, in txt2bytes format)] [--ctd ctdfilename]\n" +
"                 [{-o, --optimizer} optimizerClassName] [{-t, --threshold} costsaving_threshold]" + 
"                 [-d debugflagint=0]");
    }

	public static void main(String args[]) throws
            java.lang.ClassNotFoundException, java.lang.NoSuchMethodException, 
            java.lang.InstantiationException, java.lang.IllegalAccessException, 
            java.lang.reflect.InvocationTargetException
        {
	        CmdLineParser parser = new CmdLineParser();
		CmdLineParser.Option ccd = parser.addStringOption("ccd");
		CmdLineParser.Option cc = parser.addStringOption("cc");
		CmdLineParser.Option ctd = parser.addStringOption("ctd");
		CmdLineParser.Option optoption = parser.addStringOption('o', "optimizer");
		CmdLineParser.Option thresh = parser.addDoubleOption('t', "threshold");
		CmdLineParser.Option debugoption = parser.addIntegerOption('d', "debugflag");

		try {
		    parser.parse(args);
		}
		catch ( CmdLineParser.OptionException e ) {
		    System.err.println(e.getMessage());
		    printUsage();
		    System.exit(2);
		}

		String ccdfilename = (String)parser.getOptionValue(ccd, Optimizer.DEFAULT_CCD);
		String ccfilename = (String)parser.getOptionValue(cc, Optimizer.DEFAULT_CC);
		String ctdfilename = (String)parser.getOptionValue(ctd, Optimizer.DEFAULT_CTD);
		String optimizerclassname = (String)parser.getOptionValue(optoption, Optimizer.DEFAULT_OPTNAME);
		Double threshold = (Double) parser.getOptionValue(thresh, 0.0);
		Integer debugflag = (Integer) parser.getOptionValue(debugoption, 0);

		if (threshold < 0.0) {
		    System.err.println("cost threshold value must be non-negative");
		    System.exit(1);
		}

		String[] otherArgs = parser.getRemainingArgs();
		if (otherArgs.length != 0) {
		    System.err.println("Unrecognized arguments provided");
		    printUsage();
		    System.exit(3);
		}
		
		System.out.println("Running with options:");
		System.out.println("  ccd: "+ccdfilename);
		System.out.println("  cc: "+ ccfilename);
		System.out.println("  ctd: " +ctdfilename);
		System.out.println("  optimizer: " +optimizerclassname);
		System.out.println("  threshold: "+ threshold);
		System.out.println("  debugOption: "+ debugflag);

		// create  optimizer
                System.out.println(" Creating Optimizer " + optimizerclassname);
//		Optimizer opt = new GreedyOptimizer(ccdfilename);
                Class optclass = Class.forName(optimizerclassname);
                Constructor ccdconstructor = optclass.getConstructor("".getClass());
                Optimizer opt = (Optimizer) ccdconstructor.newInstance(ccdfilename);
                opt.setDebugFlag(debugflag);
		
		// load context characteristics data
               System.out.println(" Loading context characteristics data");
		opt.loadContextData(ccfilename);
		
		// find the optimal context tree
               System.out.println(" Finding optimal context tree");
		ContextTreeNode optTree = opt.findOptimalContextTree(threshold.doubleValue());
		
		// label context tree
		opt.labelContextTree(optTree);
		
		// output context tree content
		opt.saveContextTree(optTree, ctdfilename);
	}
}
